package com.hxl.linuxfilemanager.controller;

import com.hxl.linuxfilemanager.config.LinuxPropertiesConfig;
import com.hxl.linuxfilemanager.entity.ErrorConstant;
import com.hxl.linuxfilemanager.entity.FileEntity;
import com.hxl.linuxfilemanager.entity.R;
import com.hxl.linuxfilemanager.exceptions.SysException;
import com.hxl.linuxfilemanager.service.impl.FileServiceImpl;
import com.hxl.linuxfilemanager.util.FileUtils;
import com.hxl.linuxfilemanager.util.ResponseUtils;
import net.coobird.thumbnailator.Thumbnails;
import net.lingala.zip4j.ZipFile;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

@RestController
@RequestMapping("api/res")

public class ResController {
    private Logger logger = LoggerFactory.getLogger(ResController.class.getName());

    @Autowired
    ResourceLoader resourceLoader;

    @Autowired
    FileServiceImpl fileService;


    @Autowired
    LinuxPropertiesConfig linuxPropertiesConfig;

    /**
     * 获取文件图片
     * @param path
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/convertIcon")
    public ResponseEntity<?> convertFileIcon(@RequestParam("path") String path) throws IOException {
        File file = new File(path);
        /**
         * 如果不是图片，则在classpath下找出这个文件的扩展图标
         */
        if (!FileUtils.isImage(file)) {
            FileEntity fileEntity = fileService.createFileEntity(file);
            ClassPathResource classPathResource = new ClassPathResource(fileEntity.getExtendImage());
            byte[] bytes = IOUtils.toByteArray(classPathResource.getInputStream());
            return FileUtils.export("name", bytes);
        }
        /**
         * 是图片的话直接返回这个图片
         */
        return FileUtils.export(file.getName(),FileUtils.imageToBytes(Thumbnails.of(file).outputQuality(0.3).scale(0.5).asBufferedImage(),"jpg"));
    }


    /**
     * 下载文件
     *
     * @param path 路径
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "download")
    public ResponseEntity<?> getRes(@RequestParam("path") String path) throws IOException {

        File file = new File(path);

        /**
         * 如果是文件夹，打包成zip进行下载
         */
        if (file.isDirectory()) {
            /**
             * 构建ZIP对象
             */
            File zipFile = new File(file.getParent(), FileUtils.generatorTempZipName(file));
            new ZipFile(zipFile).addFolder(file);

            /**
             * 构建响应对象，由于实现读取到了内存，所以可直接删除零时文件。
             */
            ResponseEntity<byte[]> export = FileUtils.export(zipFile.getName(), Files.readAllBytes(Paths.get(zipFile.getAbsolutePath())));
            Files.deleteIfExists(Paths.get(zipFile.getAbsolutePath()));
            return export;
        }
        /**
         * 直接导出
         */
        return FileUtils.export(file);
    }

    /**
     * 删除文件
     *
     * @param path
     * @return
     */

    @PostMapping("delete")
    public R deleteFile(@RequestParam("file") String path) {
        File file = new File(path);
        if (file.isFile()) {
            logger.info("删除文件{}", file.getAbsolutePath());
            file.delete();
            return ResponseUtils.suceess("删除成功", "{}");
        }
        try {
            org.apache.commons.io.FileUtils.deleteDirectory(file);
            return ResponseUtils.suceess("删除成功", "{}");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ResponseUtils.error(ErrorConstant.ERROR, "无法删除目录文件");
    }


    /**
     * 文件上传
     *
     * @param path
     * @param multipartFile
     * @return
     */
    @PostMapping("upload")
    public R uploadFile(
            @RequestParam("path") String path,
            @RequestParam("upfile") MultipartFile multipartFile) {
        /**
         * 如果上传路径存在
         */
        if (Files.exists(Paths.get(path))) {
            if (Files.notExists(Paths.get(path, multipartFile.getOriginalFilename()))) {
                logger.info("上传路径{},文件名称{}", path, multipartFile.getOriginalFilename());
                try {
                    boolean result = fileService.saveFile(multipartFile.getInputStream(), path + "/" + multipartFile.getOriginalFilename());
                    if (result) {
                        return ResponseUtils.suceess("ok", "{}");
                    }
                } catch (IOException e) {
                    return ResponseUtils.error(ErrorConstant.ERROR, e.getMessage());
                }
            } else {
                return ResponseUtils.error(ErrorConstant.ERROR, "文件存在，请重复名后上传");
            }
        }
        logger.info("文件夹{}不存在", multipartFile.getName());
        return ResponseUtils.error(ErrorConstant.ERROR, "文件路径不存在");
    }

    /**
     * 获取文件内容
     *
     * @param filePath
     * @return
     */
    @PostMapping("getFileContent")
    public R getFileContent(@RequestParam("file") String filePath) {
        Path path = Paths.get(filePath);

        if (Files.notExists(path)) {
            return ResponseUtils.error(ErrorConstant.ERROR, "文件不存在");
        }
        if (Files.isDirectory(path)) {
            return ResponseUtils.error(ErrorConstant.ERROR, "不是文件");
        }

        try {

            byte[] bytes = Files.readAllBytes(path);
            return ResponseUtils.suceess("OK", new String(bytes, "utf-8"));

        } catch (IOException e) {
            e.printStackTrace();
            throw new SysException(e.getMessage());
        }
    }

    /**
     * 设置文件内容
     *
     * @param path
     * @param content
     * @return
     */

    @PostMapping("setFileContent")
    public R setFileContent(@RequestParam("file") String path, @RequestParam("content") String content) {
        if (Files.isDirectory(Paths.get(path))) {
            return ResponseUtils.error(ErrorConstant.ERROR, "不是文件");
        }
        try {
            Files.write(Paths.get(path), content.getBytes());
            return ResponseUtils.suceess("保存成功", "{}");
        } catch (IOException e) {
            throw new SysException(e.getMessage());
        }
    }
}
